package com.suntront.module_arcgis.arcgis

import android.Manifest
import android.graphics.Color
import android.os.Bundle
import android.os.Message
import android.view.MotionEvent
import android.view.View
import android.widget.TextView
import androidx.lifecycle.Observer
import com.alibaba.android.arouter.facade.annotation.Route
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment
import com.esri.arcgisruntime.geometry.*
import com.esri.arcgisruntime.layers.ArcGISTiledLayer
import com.esri.arcgisruntime.location.LocationDataSource
import com.esri.arcgisruntime.mapping.ArcGISMap
import com.esri.arcgisruntime.mapping.Basemap
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener
import com.esri.arcgisruntime.mapping.view.Graphic
import com.esri.arcgisruntime.mapping.view.LocationDisplay
import com.esri.arcgisruntime.symbology.SimpleFillSymbol
import com.esri.arcgisruntime.symbology.SimpleLineSymbol
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol
import com.mtjsoft.www.kotlinmvputils.base.BaseActivity
import com.mtjsoft.www.kotlinmvputils.constants.RouterConstants
import com.mtjsoft.www.kotlinmvputils.imp.PermissionsResultListener
import com.mtjsoft.www.kotlinmvputils.utils.KLog
import com.suntront.module_arcgis.R
import kotlinx.android.synthetic.main.activity_arcgis.*
import java.util.*
import kotlin.math.roundToInt

/**
 * GIS地图
 */
@Route(path = RouterConstants.GIS_GISMAP)
class ArcGisDemoActivity : BaseActivity<ArcGisViewModel>(), View.OnClickListener {

    private val permissions: ArrayList<String> = object : ArrayList<String>() {
        init {
            add(Manifest.permission.INTERNET)
            add(Manifest.permission.READ_EXTERNAL_STORAGE)
            add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            add(Manifest.permission.ACCESS_FINE_LOCATION)
            add(Manifest.permission.ACCESS_COARSE_LOCATION)
        }
    }
    val url = "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer"
    private lateinit var textView: TextView

    override fun layoutResId(): Int {
        return R.layout.activity_arcgis
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        // 去除开发者水印
        ArcGISRuntimeEnvironment.setLicense("runtimelite,1000,rud6884388111,none,5H80TK8EL7G4NERL1170")
        super.onCreate(savedInstanceState)
    }

    override fun initView() {
        setPageTitle("Arcgis地图")
        textView = View.inflate(
            getContext(),
            R.layout.text_layout, null
        ) as TextView
        setPermissionsList(permissions)
        requestPermission(permissions, false, object : PermissionsResultListener {
            override fun onPermissionGranted() {
                val arcGISTiledLayer = ArcGISTiledLayer(url)
                val map = ArcGISMap(Basemap(arcGISTiledLayer))
                mapView.map = map
                val gpsPoint = Point(113.498427, 34.797040)
                val mapPoint: Point =
                    GeometryEngine.project(gpsPoint, SpatialReference.create(4236)) as Point
                mapView.setViewpointCenterAsync(mapPoint, 16.0)
            }

            override fun onPermissionDenied() {
            }
        })
        // 添加绘制图层
        mapView.graphicsOverlays.add(viewModel.getGraphicsOverlay().value)
    }


    override fun onClick(p0: View) {
        super.onClick(p0)
        when (p0.id) {
            R.id.clear -> {
                clear()
            }
            R.id.location -> {
                startLocation()
            }
        }
    }

    override fun initData() {
        clear.setOnClickListener(this)
        location.setOnClickListener(this)
        radiogroup.setOnCheckedChangeListener { group, checkedId ->
            when (checkedId) {
                R.id.rb_draw_point -> {
                    viewModel.setDrowType(0)
                }
                R.id.rb_draw_polyline -> {
                    viewModel.setDrowType(1)
                }
                R.id.rb_draw_polygon -> {
                    viewModel.setDrowType(2)
                }
            }
        }
        viewModel.getDrowType().observe(this, Observer { t ->
            //清除绘制图层
            clear()
            when (t) {
                0 -> {
                    // 点击绘制点
                    mapView.onTouchListener =
                        object : DefaultMapViewOnTouchListener(this, mapView) {
                            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
                                // 屏幕坐标转换成 arcgis地图坐标
                                val clickPoint: Point = mapView.screenToLocation(
                                    android.graphics.Point(
                                        e.x.roundToInt(), e.y.roundToInt()
                                    )
                                )
                                // 点样式
                                val simpleMarkerSymbol =
                                    SimpleMarkerSymbol(
                                        SimpleMarkerSymbol.Style.CIRCLE,
                                        Color.RED,
                                        20f
                                    )
                                val graphic = Graphic(clickPoint, simpleMarkerSymbol)
                                // 添加新的点
                                viewModel.getGraphicsOverlay().value!!.graphics.add(graphic)
                                showCallout(clickPoint, "X:${clickPoint.x},Y:${clickPoint.y}")
                                return super.onSingleTapConfirmed(e)
                            }
                        }
                }
                1 -> {
                    // 点击绘制线
                    mapView.onTouchListener =
                        object : DefaultMapViewOnTouchListener(this, mapView) {
                            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
                                // 屏幕坐标转换成 arcgis地图坐标
                                val clickPoint: Point = mapView.screenToLocation(
                                    android.graphics.Point(
                                        e.x.roundToInt(), e.y.roundToInt()
                                    )
                                )
                                // 添加到点集合
                                viewModel.getPointCollection().value?.add(clickPoint)
                                val polyline = Polyline(viewModel.getPointCollection().value)
                                // 点样式
                                val simpleMarkerSymbol =
                                    SimpleMarkerSymbol(
                                        SimpleMarkerSymbol.Style.CIRCLE,
                                        Color.RED,
                                        20f
                                    )
                                val pointGraphic = Graphic(clickPoint, simpleMarkerSymbol)
                                // 绘制点
                                viewModel.getGraphicsOverlay().value!!.graphics.add(pointGraphic)

                                //线样式
                                val simpleLineSymbol = SimpleLineSymbol(
                                    SimpleLineSymbol.Style.SOLID,
                                    Color.parseColor("#FC8145"),
                                    3f
                                )
                                val lineGraphic = Graphic(polyline, simpleLineSymbol)
                                // 绘制线
                                viewModel.getGraphicsOverlay().value!!.graphics.add(lineGraphic)
                                if (viewModel.getPointCollection().value!!.size >= 2) {
                                    // 计算线距离
                                    val pathGeometry =
                                        GeometryEngine
                                            .densifyGeodetic(
                                                polyline,
                                                1.0,
                                                LinearUnit(LinearUnitId.METERS),
                                                GeodeticCurveType.GEODESIC
                                            )
                                    // calculate the path distance
                                    val distance = GeometryEngine.lengthGeodetic(
                                        pathGeometry,
                                        LinearUnit(LinearUnitId.KILOMETERS),
                                        GeodeticCurveType.GEODESIC
                                    )
                                    showCallout(
                                        clickPoint,
                                        "面积${String.format("%.2f", distance)}Km"
                                    )
                                }
                                return super.onSingleTapConfirmed(e)
                            }
                        }
                }
                2 -> {
                    // 点击绘制面
                    mapView.onTouchListener =
                        object : DefaultMapViewOnTouchListener(this, mapView) {
                            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
                                // 屏幕坐标转换成 arcgis地图坐标
                                val clickPoint: Point = mapView.screenToLocation(
                                    android.graphics.Point(
                                        e.x.roundToInt(), e.y.roundToInt()
                                    )
                                )
                                // 添加到点集合
                                viewModel.getPointCollection().value?.add(clickPoint)
                                val polygon = Polygon(viewModel.getPointCollection().value)
                                // 点样式
                                val simpleMarkerSymbol =
                                    SimpleMarkerSymbol(
                                        SimpleMarkerSymbol.Style.CIRCLE,
                                        Color.RED,
                                        20f
                                    )
                                val pointGraphic = Graphic(clickPoint, simpleMarkerSymbol)
                                // 绘制点
                                viewModel.getGraphicsOverlay().value!!.graphics.add(pointGraphic)

                                //线样式
                                val lineSymbol = SimpleLineSymbol(
                                    SimpleLineSymbol.Style.SOLID,
                                    Color.GREEN, 3.0f
                                )
                                // 填充样式
                                val simpleFillSymbol = SimpleFillSymbol(
                                    SimpleFillSymbol.Style.SOLID,
                                    Color.parseColor("#33e97676"),
                                    lineSymbol
                                );
                                val graphic = Graphic(polygon, simpleFillSymbol)
                                // 绘制线
                                viewModel.getGraphicsOverlay().value!!.graphics.add(graphic)
                                if (viewModel.getPointCollection().value!!.size >= 3) {
                                    // 计算面积
                                    val pathGeometry =
                                        GeometryEngine
                                            .densifyGeodetic(
                                                polygon,
                                                1.0,
                                                LinearUnit(LinearUnitId.METERS),
                                                GeodeticCurveType.GEODESIC
                                            )
                                    val area = GeometryEngine.areaGeodetic(
                                        pathGeometry,
                                        AreaUnit(AreaUnitId.SQUARE_KILOMETERS),
                                        GeodeticCurveType.GEODESIC
                                    )
                                    showCallout(clickPoint, "面积${String.format("%.2f", area)}Km²")
                                }
                                return super.onSingleTapConfirmed(e)
                            }
                        }
                }
            }
        })
    }

    /**
     * 显示气泡Callout
     */
    private fun showCallout(point: Point, msg: String) {
        textView.text = msg
        if (mapView.callout.isShowing) {
            mapView.callout.dismiss()
        }
        mapView.callout.show(textView, point)
    }

    /**
     * 清除图层显示
     */
    private fun clear() {
        viewModel.getGraphicsOverlay().value!!.graphics.clear()
        viewModel.getPointCollection().value?.clear()
        if (mapView.callout.isShowing) {
            mapView.callout.dismiss()
        }
    }

    /**
     * 开始定位
     */
    private fun startLocation() {
        // 定位及自动扫描模式
        val locationDisplay = mapView.locationDisplay
        locationDisplay.autoPanMode = LocationDisplay.AutoPanMode.RECENTER
        locationDisplay.isShowAccuracy = false;//隐藏符号的缓存区域
        viewModel.setLocationDisplay(locationDisplay)
        // 当我们执行LocationDisplay.startAsync()方法时候，会在地图上显示出我们当前位置
        viewModel.getLocationDisplay().value?.startAsync()
        // 1 获取的点是基于当前地图坐标系的点
//        val point = viewModel.getLocationDisplay().value!!.mapLocation
        // 2 获取基于GPS的位置信息
//        val location: LocationDataSource.Location = viewModel.getLocationDisplay().value!!.location
        // 3 基于WGS84的经纬度坐标
//        val point1 = location.position
        // 如果要在LocationDisplay里进行位置信息的自动监听，方法也很简单，只需要LocationDisplay.addLocationChangedListener即可
        viewModel.getLocationDisplay().value!!.addLocationChangedListener {
            // GPS坐标
            val location: LocationDataSource.Location = it.location
            KLog.e(location.position.toString())
        }
    }

    override fun providerVMClass(): Class<ArcGisViewModel>? {
        return ArcGisViewModel::class.java
    }

    override fun processHandlerMsg(msg: Message) {
    }

    override fun onPause() {
        super.onPause()
        mapView.pause()
    }

    override fun onResume() {
        super.onResume()
        mapView.resume()
    }

    override fun onDestroy() {
        if (viewModel.getLocationDisplay().value != null && viewModel.getLocationDisplay().value!!.isStarted) {
            viewModel.getLocationDisplay().value!!.stop()
        }
        super.onDestroy()
        mapView.dispose()
    }
}
